import Taro, {getCurrentPages, getCurrentInstance} from "@tarojs/taro";
import {cloneDeep} from "lodash";
import moment from 'moment';
import request from "../service/api";
import {getStationList, getRateDetail, getPileDetail} from "../service/station";
import {getGunStatus} from '../utils/index';

const delay = (timeout) => new Promise((resolve) => setTimeout(resolve, timeout || 0));
let Timer; // 90s倒计时定时器
let timer; // 检查枪状态
export default {
  namespace: "stations",
  state: {
    tabKey: 0,
    searchValue: "",
    selectGunCode: "",
    allActivities: [], //当前时段进行的活动
    myCoupons: [], //已领取的券(全部)
    myCouponsByStation: [], //已领取的券(指定场站)
    currentCouPonType: 0, // 优惠券列表
    stationList: [],
    stationListAll: [], // 全部,用于地图上展示
    pageNum: 1,
    pageSize: 10,
    total: 0,
    showStartModal: false,
    orderStarting: false,
    errorMsg: '',
    action: undefined,
    countDownTime: 90,
    isMine: false
  },
  subscriptions: {},
  effects: {
    * init({payload}, {put, select, call, all}) {
      console.log('首页init传值', payload);
      const {action = undefined} = payload;
      const {searchValue, pageSize} = yield select(({stations}) => stations);
      Taro.removeStorageSync('useDidShowQuery');
      yield call(() => delay(100));
      yield all([
        put({type: 'load', payload: {pageNum: 1, pageSize: pageSize || 10, searchText: searchValue}}),
        put({type: 'loadAll'}),
        put({type: 'upState', payload: {action: action}})
      ]);
    },
    * load({payload}, {call, put}) {
      const {pageNum = 1, pageSize = 20, searchText = ''} = payload;
      const currentLocation = Taro.getStorageSync('currentLocation') ? JSON.parse(Taro.getStorageSync('currentLocation')) : {}
      yield call(() => delay(300));
      const res = yield call(() => getStationList({
        searchText,
        latitude: currentLocation.latitude,
        longitude: currentLocation.longitude,
        pageNum,
        pageSize
      }));
      const {code, data} = res;
      if (code === 200) {
        yield put({
          type: 'upState',
          payload: {
            stationList: data.records,
            searchValue: searchText,
            pageNum,
            pageSize,
            total: data?.total || 0
          }
        })
      }
    },
    * loadAll(_, {call, put}) {
      const currentLocation = Taro.getStorageSync('currentLocation') ? JSON.parse(Taro.getStorageSync('currentLocation')) : {}
      const res = yield call(() => getStationList({
        latitude: currentLocation.latitude,
        longitude: currentLocation.longitude,
        pageNum: 1,
        pageSize: 10000
      }));
      const { code, data } = res;
      if (code === 200) {
        yield put({
          type: 'upState',
          payload: {
            stationListAll: data.records
          }
        })
      }
    },
    * goStationDetail({payload}, {put, call}) {
      const {current} = payload;
      const {pileIds, stationId} = current;
      const res = yield call(() => request.post('/mini/stationInfo/v2', {pileIds, stationId}))
      const {data: {data = [], code}} = res;
      if (code && code === 200) {
        yield put({
          type: 'upState',
          payload: {
            currentStation: {
              ...current,
              piles: [
                ...data
              ]
            }
          }
        });
        yield put({type: 'getRateDetail', payload: {ruleId: current?.ruleId}});
        Taro.navigateTo({url: `/pages/index/detail?stationId=${current.stationId}&stationName=${current.stationName}&pileIds=${current.pileIds}`})
      } else {
        Taro.showToast({
          title: '场站信息获取失败,请重试',
          duration: 1000,
          icon: 'none'
        })
      }
    },
    * initDetail({payload}, {put, call}) {
      const {current} = payload;
      const {pileIds, stationId} = current;
      const res = yield call(() => request.post('/mini/stationInfo/v2', {pileIds, stationId}))
      const {data: {data = [], code}} = res;
      if (code && code === 200) {
        yield put({
          type: 'upState',
          payload: {
            currentStation: {
              ...current,
              piles: [
                ...data
              ]
            }
          }
        });
        yield put({type: 'getRateDetail', payload: {ruleId: current?.ruleId}});
      }
    },
    * upStatePile({payload}, {put}) {
      const {currentPile} = payload;
      yield put({
        type: 'upState',
        payload: {
          currentPile: {...currentPile}
        }
      });
      yield put({type: 'getRateDetail', payload: {ruleId: currentPile?.rulesId}})
    },
    // 扫码进入小程序逻辑
    * jumpToPile({payload}, {call, put}) {
      console.log('扫码进入小程序获取桩详情传参', payload)
      const {gunCode} = payload;
      const res = yield call(() => getPileDetail(payload));
      console.log('扫码进入小程序获取桩详情回调', res)
      const {data: {data, code, msg}} = res;
      if (code && code === 200) {
        const {miniRateInfos = [], scanGunInfos = []} = data;
        yield put({
          type: 'upState',
          payload: {
            rateDetail: miniRateInfos.length ?
              miniRateInfos.sort((pre, cur) => parseInt(pre.timeStr.substr(0, 2)) - parseInt(cur.timeStr.substr(0, 2))) : [],
            currentPile: {...data, gunInfo: []},
            selectGunCode: parseInt(data?.gunCode),
            currentGun: {
              ...data, gunInfo: [],
              gunIndex: parseInt(data?.gunCode),
              gunStatus: getGunStatus(data?.gunCodeStatus),
              rateDetail: miniRateInfos.length ?
                miniRateInfos.sort((pre, cur) => parseInt(pre.timeStr.substr(0, 2)) - parseInt(cur.timeStr.substr(0, 2))) : []
            }
          }
        })
        setTimeout(() => Taro.reLaunch({url: '/moduleA/pages/pile/index'}), 500)
      } else {
        Taro.showToast({
          title: msg || '桩详情信息查询失败',
          duration: 1500,
          icon: 'none'
        })
      }
    },
    * backToPile({payload}, {call, put}) {
      console.log('backToPile', payload);
      const {gunCode, needJump = false} = payload;
      yield put({
        type: 'upState',
        payload: {
          currentPile: {}
        }
      })
      const res = yield call(() => getPileDetail(payload));
      console.log('backToPileRES', res);
      const {data: {data, code, msg = ''}} = res;
      if (code && code === 200) {
        const {miniRateInfos = [], scanGunInfos = []} = data;
        console.log('gunCode', parseInt(data?.gunCode))
        yield put({
          type: 'upState',
          payload: {
            rateDetail: miniRateInfos.length ?
              miniRateInfos.sort((pre, cur) => parseInt(pre.timeStr.substr(0, 2)) - parseInt(cur.timeStr.substr(0, 2))) : [],
            currentPile: {...data, gunInfo: []},
            selectGunCode: parseInt(data?.gunCode),
            currentGun: {
              ...data, gunInfo: [],
              gunIndex: parseInt(data?.gunCode),
              gunStatus: getGunStatus(data?.gunCodeStatus),
              rateDetail: miniRateInfos.length ?
                miniRateInfos.sort((pre, cur) => parseInt(pre.timeStr.substr(0, 2)) - parseInt(cur.timeStr.substr(0, 2))) : []
            }
          }
        })
        if (needJump) Taro.navigateTo({url: "/moduleA/pages/pile/index"})
      } else {
        Taro.showToast({
          title: msg || '桩详情信息查询失败',
          duration: 1500,
          icon: 'none'
        })
      }
    },
    // 查询全部场站当前时段正在进行的活动信息
    * getAllActivity(_, {call, put}){
      const {data: {code, data = []}} = yield call(() => request.post('/mini/activity/all', {stationId: ''}));
      if (code && code === 200){
        const list = data.length ? data.filter((l) => moment(l.activityEndTime) >= moment()).map((i) => {
          return {
            ...i,
            coupons: i.voList.length ? [...i.voList] : []
          }
        }) : [];
        yield put({
          type: 'upState',
          payload: {
            allActivities: [...list]
          }
        })
        // yield delay(1000);
        yield put({type: 'getMyCoupons'});
      }
      // console.log('DATA', data);
    },
    // 查询指定场站当前时段正在进行的活动信息
    * getAllActivityByStation(_, {call, put, select}){
      const {currentPile} = yield select(({stations}) => stations);
      const {data: {code, data = []}} = yield call(() => request.post('/mini/activity/all', {stationId: currentPile?.stationId}));
      if (code && code === 200){
        const list = data.length ? data.map((i) => {
          return {
            ...i,
            coupons: i.voList.length ? [...i.voList] : []
          }
        }) : [];
        yield put({
          type: 'upState',
          payload: {
            allActivities: [...list]
          }
        });
        yield delay(300);
        yield put({type: 'getMyCouponsByStation'});
      }
    },
    //参加活动(领券优惠券)
    *attendActivity({payload}, {call, put}){
      const {data: {code, msg}} = yield call(() => request.post('/mini/activity/create', {...payload}));
      if (code && code === 200){
        Taro.showToast({
          title: '领取成功',
          icon: 'success'
        });
        yield put({type: 'getMyCoupons'});
        // yield put({type: 'getAllActivity'});
      } else {
        Taro.showToast({
          title: msg,
          icon: 'none'
        })
      }
    },
    // 获取用户当前的优惠券
    *getMyCoupons(_, {call, put}){
      const {data: {code, data}} = yield call(() => request.post('/mini/activity/couponPage', {
        chargeStationId: '',
        pageNum: 1,
        pageSize: 10000
      }));
      if (code && code === 200){
        const myOwn = data?.records && data?.records.length ? data?.records.filter( item => item.status === 10) : [];
        yield put({
          type: 'upState',
          payload: {
            myCoupons: data?.records || [],
            myCouponsActive: myOwn || []
          }
        })
      }
    },
    // 获取用户在指定场站可用的优惠券
    *getMyCouponsByStation(_, {call, select, put}){
      const {currentPile} = yield select(({stations}) => stations);
      const {data: {code, data}} = yield call(() => request.post('/mini/activity/couponPage', {
        chargeStationId: currentPile?.stationId,
        pageNum: 1,
        pageSize: 10000
      }));
      if (code && code === 200){
        const myOwn = data?.records && data?.records.length && data?.records.filter((r) => r.status === 10) || [];
        yield put({
          type: 'upState',
          payload: {
            myCouponsByStation: myOwn
          }
        })
      }
    },
    * getRateDetail({payload}, {call, put}) {
      const {ruleId} = payload;
      const {data: {data = [], code}} = yield call(() => getRateDetail(ruleId));
      if (code && code === 200) {
        yield put({
          type: 'upState',
          payload: {
            rateDetail: data.length ? data.sort((pre, cur) => {
              if (parseInt(pre.timeStr.substr(0, 2)) !== parseInt(cur.timeStr.substr(0, 2))){
                return parseInt(pre.timeStr.substr(0, 2)) - parseInt(cur.timeStr.substr(0, 2))
              } else {
                return parseInt(pre.timeStr.substr(3, 2)) - parseInt(cur.timeStr.substr(3, 2))
              }
            }) : []
          }
        })
      }
    },
    * createOrder({payload}, {call, put, select}) {
      const {action, currentGun, countDownTime} = yield select(({stations}) => stations);
      let temC = cloneDeep(countDownTime);
      for (const d in payload){
        if (!payload[d]){
          delete payload[d]
        }
      }
      const {pileType} = payload;
      console.log('创建订单接口传参', payload);
      console.log('currentGun', currentGun);
      const param = {
        ...payload
      };
      delete param.pileType;
      if (payload.payType === 2){
        delete param.couponName;
        delete param.couponId;
      }
      const res = yield call(() => request.post(payload.payType === 2 ? '/order/createPointOrder' : '/mini/order/createOrder', {...payload}));
      // yield call(() => delay(3000));
      console.log('创建订单接口回调', res);
      const {data = {}, statusCode} = res;
      if (res && statusCode && statusCode === 200) {
        yield put({type: 'upState', payload: {showStartModal: true, errorMsg: ''}})
        const {code: responseCode, msg = ''} = data;
        // yield put({type: 'upState', payload: {currentOrderNum: msg}})
        // Taro.setStorageSync('timeStampForChargingOrderCreate', new Date().getTime());
        // Taro.setStorageSync('pramaObjForChargingOrderCreate', JSON.stringify({gunCode: currentGun?.gunIndex, pileId: currentGun?.pileId, currentOrderNum: msg}));
        if (responseCode !== 200) {
          yield put({type: 'upState', payload: {errorMsg: msg}})
        } else {
          yield put({type: 'upState', payload: {currentOrderNum: msg}})
          Taro.setStorageSync('timeStampForChargingOrderCreate', new Date().getTime());
          Taro.setStorageSync('pramaObjForChargingOrderCreate', JSON.stringify({
            gunCode: currentGun?.gunIndex,
            // pileId: currentGun?.pileId,
            pileCode: currentGun?.pileCode,
            currentOrderNum: msg
          }));
          Taro.showToast({
            title: '订单创建成功,正在启动充电...',
            icon: 'none',
            duration: 1000
          });
          if (action) {
            clearInterval(Timer);
            Timer = setInterval(() => {
              temC--;
              action({
                type: 'stations/upState',
                payload: {
                  countDownTime: temC
                }
              })
            }, 1000)
            // yield call(delay(30000)); // 延迟30s后请求枪的开启状态
            console.log('pileType', pileType)
            yield call(delay, pileType && pileType === '交流慢充' ? 5000 : 30000);// 交流延迟5s,直流延迟30s后请求枪的开启状态
            clearInterval(timer);
            timer = setInterval(() => {
              action({
                type: 'stations/checkGunStatus',
                payload: {
                  gunCode: currentGun?.gunIndex,
                  // pileId: currentGun?.pileId,
                  pileCode: currentGun?.pileCode,
                  currentOrderNum: msg
                }
              })
            }, 1000)
          }
        }
      }
    },
    * checkGunStatus({payload}, {call, put}) {
      console.log('检查枪启动状态接口传值', payload);
      const {gunCode, pileCode, currentOrderNum} = payload;
      const timeStampForChargingOrderCreate = Taro.getStorageSync('timeStampForChargingOrderCreate');
      const nowTimeStamp = new Date().getTime();
      const diffSecond = timeStampForChargingOrderCreate ? 90 - parseInt((nowTimeStamp - timeStampForChargingOrderCreate) / 1000) : 0;
      console.log('checkGunStatusDiffSecond', diffSecond)
      console.log('timeStampForChargingOrderCreate', timeStampForChargingOrderCreate)
      if (timeStampForChargingOrderCreate){
        if (diffSecond <= 0) {
          if (currentOrderNum){
            yield put({ // 启动超时,手动生成异常单子
              type: 'createBadOrder',
              payload: {
                orderNum: currentOrderNum,
                status: 2
              }
            });
          }
          clearInterval(timer);
          clearInterval(Timer);
          return;
        }
        const res = yield call(() => request.get('/mini/getGunStatus', {gunCode, pileCode}));
        console.log('检查枪启动状态接口回调', res);
        const {data: {data, code}} = res;
        if (code && code === 200) {
          // 2:已插枪; 3:启动成功; 4:启动异常
          if (data !== 2){
            if (data === 3) {
              clearInterval(timer);
              yield call(delay, 1000);
              clearInterval(Timer);
              Taro.removeStorage({key: 'timeStampForChargingOrderCreate'})
              Taro.removeStorage({key: 'pramaObjForChargingOrderCreate'})
              yield put({
                type: 'upState',
                payload: {errorMsg: '启动成功,正在充电', showStartModal: false, countDownTime: 90}
              });
              Taro.showToast({
                title: '启动成功,正在充电...',
                icon: 'none',
                duration: 2000
              });
              Taro.setStorageSync('timeStampForChargingBegin', new Date().getTime());
              Taro.setStorageSync('timeStampChargingBegin', new Date().getTime());
              yield put({type: 'getChargingOrderInfo'});
              Taro.reLaunch({url: '/moduleA/pages/charging/index'});
            } else if (data === 4) {
              clearInterval(timer);
              clearInterval(Timer);
              Taro.removeStorage({key: 'timeStampForChargingOrderCreate'})
              Taro.removeStorage({key: 'pramaObjForChargingOrderCreate'})
              yield put({type: 'upState', payload: {errorMsg: '设备故障,启动失败', countDownTime: 90}});
            } else {
              clearInterval(timer);
              clearInterval(Timer);
              Taro.removeStorage({key: 'timeStampForChargingOrderCreate'})
              Taro.removeStorage({key: 'pramaObjForChargingOrderCreate'});
              yield put({type: 'upState', payload: {errorMsg: '启动失败,请重新插枪,扫码', countDownTime: 90}});
            }
          }
        }
      } else {
        clearInterval(timer);
        clearInterval(Timer);
        Taro.removeStorage({key: 'timeStampForChargingOrderCreate'})
        Taro.removeStorage({key: 'pramaObjForChargingOrderCreate'});
        return;
      }
    },
    // 生成异常单
    * createBadOrder({payload}, {call, put}) {
      // const res = yield call (() => request.post('/mini/order/await', {...payload}));
      // console.log('请求接口生成异常单回调', res);
      console.log('90s超时已到...弹框提示超时(取消调用接口)')
      clearInterval(timer);
      clearInterval(Timer);
      Taro.removeStorage({key: 'timeStampForChargingOrderCreate'})
      Taro.removeStorage({key: 'pramaObjForChargingOrderCreate'})
      yield put({
        type: 'upState',
        payload: {
          errorMsg: '启动超时,请重新插枪,扫码',
          countDownTime: 90
        }
      });
    },
    *initCharging(_, {put}){
      yield put({
        type: 'upState',
        payload: {
          stopBtnDisabled: true,
        }
      })
      yield put({type: 'getChargingOrderInfo'})
    },
    *initChargingPage(_, {call, put}){
      const currentRouter = getCurrentInstance()?.router || {}; // 路由参数
      yield put({
        type: 'upState',
        payload: {
          stopBtnDisabled: true,
        }
      })
      const res = yield call(() => request.get('/system/order/findUserChargingOrder'));
      const {data: {code, data = {}} = {}} = res;
      // console.log('正在充电单子信息initChargingPage', res);
      if (code && code === 200) {
        yield put({
          type: 'upState',
          payload: {
            chargingOrderInfo: {
              ...data
            }
          }
        })
        if (!data && currentRouter.path === '/moduleA/pages/charging/index'){
          Taro.showToast({title: '订单已结束...', icon: "none"});
          yield put ({
            type:'app/upState',
            payload: {
              selected: 2
            }
          })
          setTimeout(() => {
            Taro.reLaunch({url: '/pages/mine/index'});
          }, 1000);
        }
      }
    },
    // 获取正在充电信息
    * getChargingOrderInfo(_, {call, put}) {
      const res = yield call(() => request.get('/system/order/findUserChargingOrder'));
      const {data: {code, data = {}} = {}} = res;
      // console.log('正在充电单子信息', res);
      if (code && code === 200) {
        yield put({
          type: 'upState',
          payload: {
            chargingOrderInfo: {
              ...data
            }
          }
        })
        if (!data || !Object.keys(data).length){
          Taro.removeStorage({key: 'timeStampChargingBegin'})
        }
        // if (data.orderStatus && data.orderStatus === 60){
        //   Taro.showToast({title: '订单已结束...', icon: "none"});
        //   setTimeout(() => {
        //     Taro.reLaunch({url: '/pages/mine/index'});
        //   }, 1000)
        // }
      }
    },
    // 获取是否有正在启动的单子
    * findUserLoadingOrder(_, {call, put, select}) {
      const {action, countDownTime, currentGun, currentOrderNum} = yield select(({stations}) => stations);
      const res = yield call(() => request.get('/system/order/findUserLoadingOrder'));
      console.log('否有正在启动的单子回调', res);
      const timeStampForChargingOrderCreate = Taro.getStorageSync('timeStampForChargingOrderCreate');
      const pramaObjForChargingOrderCreate = Taro.getStorageSync('pramaObjForChargingOrderCreate');
      const OBJ = pramaObjForChargingOrderCreate ? JSON.parse(pramaObjForChargingOrderCreate) : {};
      const nowTimeStamp = new Date().getTime();
      const diffSecond = timeStampForChargingOrderCreate ? 90 - parseInt((nowTimeStamp - timeStampForChargingOrderCreate) / 1000) : 0;
      console.log('diffSecond', diffSecond);
      console.log('countDownTime', countDownTime);
      const {data: {code, data = []} = {}} = res;
      console.log('启动中的订单数据', data);
      if (code && code === 200) {
        yield put({
          type: 'upState',
          payload: {
            orderStarting: !!(data && data.length),
            showStartModal: data && data.length && diffSecond > 0,
            countDownTime:  data && data.length && diffSecond > 0 ? diffSecond : 90
          }
        });
        if (data && data.length){
          if (diffSecond <= 0 || countDownTime <=0) {
            yield call(delay, 1000);
            clearInterval(timer);
            clearInterval(Timer);
            Taro.removeStorage({key: 'timeStampForChargingOrderCreate'})
            Taro.removeStorage({key: 'pramaObjForChargingOrderCreate'})
          } else {
            let temC = cloneDeep(diffSecond);
            console.log('temC', temC);
            if (action) {
              clearInterval(Timer);
              Timer = setInterval(() => {
                temC--;
                action({
                  type: 'stations/upState',
                  payload: {
                    countDownTime: temC
                  }
                })
              }, 1000)
              yield call(delay, diffSecond > 60 ? (diffSecond - 60)*1000 : 0);
              clearInterval(timer);
              timer = setInterval(() => {
                action({
                  type: 'stations/checkGunStatus',
                  payload: {...OBJ}
                })
              }, 1000)
            }
          }
        } else {
          console.log('没有正在充电的订单,清除定时器')
          clearInterval(timer);
          clearInterval(Timer);
          Taro.removeStorage({key: 'timeStampForChargingOrderCreate'})
          Taro.removeStorage({key: 'pramaObjForChargingOrderCreate'})
        }
      }
    },
    // 手动结束充电
    * finishCharge({payload}, {call, put}) {
      // console.log('结束充电传参', payload);
      const res = yield call(() => request.post('/charge/pile/shutdown', {...payload}));
      // console.log('手动结束充电接口回调', res);
      const {data: {code} = {}} = res;
      if (code && code === 200) {
        clearInterval(timer);
        clearInterval(Timer);
        Taro.showToast({title: '正在结束充电...', icon: "none", duration: 2000});
        yield put ({
          type:'app/upState',
          payload: {
            selected: 2
          }
        })
        setTimeout(() => {
          Taro.reLaunch({url: '/pages/mine/index'});
        }, 1500);
      } else {
        Taro.showToast({title: '操作失败,请稍后重试', icon: "none", duration: 1000});
        setTimeout(() => {
          Taro.redirectTo({url: '/moduleA/pages/charging/index'});
        }, 1000)
      }
    },
    // 跳转正在充电页面
    *goChargingPage(_, {call}){
      // Taro.navigateTo({url: "/moduleA/pages/charging/index"}) // 跳转至充电中页面,临时测试使用
      const res = yield call(() => request.get('/system/order/findUserChargingOrder'));
      const {data: {code, data = {}} = {}} = res;
      console.log('跳转正在充电页面', res);
      // Taro.navigateTo({url: "/moduleA/pages/charging/index"})
      if (code === 200 && data && Object.keys(data).length){
        Taro.navigateTo({url: "/moduleA/pages/charging/index"})
      } else {
        Taro.showToast({
          title: '您没有爱车正在充电....',
          icon: 'none',
          duration: 2000
        })
      }
    },
    // 模拟
    *goAboutUs(notUsed){
      Taro.navigateTo({url: "/moduleB/pages/aboutUs/index"})
    }
  },
  reducers: {
    upState(state, { payload }) {
      return {
        ...state,
        ...payload,
      };
    },
  },
};
